package src.model.gameObject.ability;

import java.util.Vector;

import src.event.events.UpdateGameDataObject;
import src.model.gameObject.GameObject;
import src.model.gameObject.GameObjectSubtype;
import src.model.gameObject.GameObjectType;
import src.model.gameObject.eventBrokers.MoveEventBroker;
import src.model.gameObject.eventInterfaces.MoveGameObjectListener;
import src.model.gameWorld.ActualMap;
import src.model.gameWorld.GameDataObject;
import src.model.gameWorld.GameWorldEventHandler;
import src.model.gameWorld.LookupTable;
import src.model.gameWorld.Position;

/**
 * <b>Overview</b><br>
 * <p>This allows a GameObject to detect traps around it. Every time that its GameObject moves, it
 * will check it's surrounding areas for traps. It is not always garunteed to find all traps. The chance
 * that it will find a trap is based upon its skill.</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>Possibly detect traps every time its gameObject moves and on new turns</p>
 * <br><br>
 * <b>Collaborators</b>
 * <br><br>
 * <b>Implementor</b> - <br>
 * <b>Tester</b> - <br>
 * @author Tristan
 *
 */
public class DetectTrap extends Ability implements MoveGameObjectListener{
	
	private ActualMap am;
	/**
	 * Constructs a new DetectTrap Ability and registers it with appropriate brokers.
	 * @param pgo The PlayerGameObject that owns this.
	 * @param lookup The LookupTable for this.
	 * @param am The ActualMap that this resides on.
	 */
	public DetectTrap(GameObject pgo, LookupTable lookup, ActualMap am) {
		super(pgo, AbilityType.DETECTTRAP, lookup);
		this.am = am;
		MoveEventBroker.register(super.gameObject(), this);
	}
	
	/**
	 * Upon notification that its GameObject moved, it looks for traps in the surrounding area.
	 * @param p The Position moved onto.
	 */
	public void notifyGameObjectMoved(Position p){
		Vector<Position> nearby = new Vector<Position>(am.positionsInRange(p, (int)super.getAttribute(AbilityAttributes.MAXIMUM)));
		for (Position tile : nearby){
			GameObject item = am.findObject(tile, GameObjectType.ITEM);
			if (item == null) continue;
			GameObjectSubtype gos = item.getSubtype();
			if (gos != GameObjectSubtype.TRAP) continue;
			GameObject cloner = item.clone();
			cloner.removeAbility(cloner.getAbility(AbilityType.INVISIBLE));
			GameDataObject trap = new GameDataObject(cloner);
			UpdateGameDataObject viewThis = new UpdateGameDataObject(tile, trap);
			GameWorldEventHandler.fireEventNow(viewThis);
		}
	}
	
	public void destroySub(){
		MoveEventBroker.unregister(super.gameObject(), this);
	}
	
	public void newTurn(){
		notifyGameObjectMoved(am.findObject(super.gameObject()));
	}
}
